/**
 * Copyright (c) 2013 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */

package com.nokia.example.composedui.views;

import java.util.Vector;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;

import com.nokia.example.composedui.ViewManager;
import com.nokia.example.composedui.model.DataItem;
import com.nokia.example.composedui.model.ItemStorage;
import com.nokia.example.composedui.utils.AppDataStorage;
import com.nokia.example.composedui.utils.Confirmation;
import com.nokia.example.composedui.utils.PersistableState;

/**
 * This is the view for deleting multiple items.
 */
public class ItemDeleteView
    extends List
    implements CommandListener, PersistableState
{
    // Constants
    private static final String STORAGE_ID_FOR_SELECTED_ITEMS_TO_BE_DELETED =
        "selectedToBeDeleted";

    // Members
    private final Command backCommand;
    private final Command deleteSelectedCommand;
    private final Command markAllCommand;
    private final Command unmarkAllCommand;
    private ViewManager viewManager;
    private ItemStorage itemStorage;

    /**
     * Constructor.
     */
    public ItemDeleteView() {
        super("Select items to be deleted", List.MULTIPLE);
        deleteSelectedCommand = new Command("OK", Command.OK, 1);
        backCommand = new Command("Back", Command.BACK, 1);
        markAllCommand = new Command("Mark all", Command.SCREEN, 1);
        unmarkAllCommand = new Command("Unmark all", Command.SCREEN, 2);
        addCommand(deleteSelectedCommand);
        addCommand(backCommand);
        addCommand(markAllCommand);
        addCommand(unmarkAllCommand);
        setCommandListener(this);
    }

    /**
     * Constructor.
     * @param itemStorage
     * @param viewManager
     */
    public ItemDeleteView(ItemStorage itemStorage, ViewManager viewManager) {
        this();
        restoreInstance(null, itemStorage, viewManager, null, null);
    }

    /**
     * @see PersistableState#restoreInstance(DataItem, ItemStorage, ViewManager, AppDataStorage, String)
     */
    public void restoreInstance(DataItem selectedDataItem,
                                ItemStorage itemStorage,
                                ViewManager viewManager,
                                AppDataStorage appDataStorage,
                                String uniqueId)
    {
        this.viewManager = viewManager;
        this.itemStorage = itemStorage;
        
        populateList(itemStorage.elements());
        
        if (appDataStorage != null) {
            String selectedIndexesStr = appDataStorage.valueByKey(
                uniqueId + STORAGE_ID_FOR_SELECTED_ITEMS_TO_BE_DELETED);
            
            if (selectedIndexesStr != null) {
                byte[] bytes = selectedIndexesStr.getBytes();
                boolean[] states = new boolean[bytes.length];
                
                for (int i = 0; i < bytes.length; i++) {
                    states[i] = (bytes[i] == 1);
                }
                
                setSelectedFlags(states);
            }
        }
    }

    /**
     * @see PersistableState#saveInstance(AppDataStorage, String)
     */
    public void saveInstance(AppDataStorage appDataStorage, String uniqueId) {
        boolean[] states = new boolean[size()];
        getSelectedFlags(states);
        
        byte[] bytes = new byte[size()];
        
        for (int i = states.length - 1; i >= 0; i--) {
            if (states[i]) {
                bytes[i] = 1;
            }
        }
        
        appDataStorage.put(uniqueId + STORAGE_ID_FOR_SELECTED_ITEMS_TO_BE_DELETED,
                           new String(bytes));
    }

    /**
     * @see javax.microedition.lcdui.CommandListener#commandAction(Command, Displayable)
     */
    public void commandAction(Command command, Displayable displayable) {
        if (deleteSelectedCommand.equals(command)) {
            int numberOfSelected = getSelectedFlags(new boolean[size()]);
            String confirmationText = "Delete " + numberOfSelected + " items?";
            Confirmation confirmation = new Confirmation(confirmationText,
                    "Delete", "Cancel", this);
            viewManager.showView(confirmation);
        }
        else if (markAllCommand.equals(command)) {
            for (int i = size() - 1; i >= 0; i--) {
                setSelectedIndex(i, true);
            }
        }
        else if (unmarkAllCommand.equals(command)) {
            for (int i = size() - 1; i >= 0; i--) {
                setSelectedIndex(i, false);
            }
        }
        else if (Confirmation.OK_COMMAND.equals(command)) {
            boolean[] states = new boolean[size()];
            getSelectedFlags(states);
            boolean notifyAtTheEnd = false;
            
            for (int i = states.length - 1; i >= 0; i--) {
                if (states[i]) {
                    itemStorage.removeElementAt(i, false);
                    notifyAtTheEnd = true;
                }
            }
            
            if (notifyAtTheEnd) {
                // At least one item was deleted
                itemStorage.saveItemsToAppDataStorage(true); // Save changes
                itemStorage.notifyItemStorageListeners();
            }
            
            viewManager.goBack(); // From Confirmation to this view
            viewManager.goBack(); // From this view to the listing
        }
        else if (Confirmation.CANCEL_COMMAND.equals(command)) {
            viewManager.goBack(); // From Confirmation to this view
            
        }
        else if (backCommand.equals(command)) {
            viewManager.goBack();
        }
    }

    /**
     * Populates the view with the given data items.
     * @param dataItems The data items to display in the view.
     */
    protected void populateList(Vector dataItems) {
        for (int i = 0; i < dataItems.size(); i++) {
            DataItem item = (DataItem)dataItems.elementAt(i);
            append(item.getName(), null);
        }
    }
}